Fix problem if itlb miss occurs when in metaphysical mode
authordjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 16 Nov 2005 22:44:49 +0000 (16:44 -0600)
committerdjm@kirby.fc.hp.com <djm@kirby.fc.hp.com>
Wed, 16 Nov 2005 22:44:49 +0000 (16:44 -0600)
xen/arch/ia64/xen/vcpu.c

index d39e4aae7c1832aa97254628e6d40a83bddda24a..9f2b0a186b1d3a180a6485b29b2c053e52045798 100644 (file)
@@ -1290,12 +1290,12 @@ int warn_region0_address = 0; // FIXME later: tie to a boot parameter?
 
 IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pteval, UINT64 *itir, UINT64 *iha)
 {
+       unsigned long region = address >> 61;
        unsigned long pta, pte, rid, rr;
        int i;
        TR_ENTRY *trp;
 
-       if (PSCB(vcpu,metaphysical_mode)) {
-               unsigned long region = address >> 61;
+       if (PSCB(vcpu,metaphysical_mode) && !(!is_data && region)) {
                // dom0 may generate an uncacheable physical address (msb=1)
                if (region && ((region != 4) || (vcpu->domain != dom0))) {
 // FIXME: This seems to happen even though it shouldn't.  Need to track
@@ -1309,7 +1309,7 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt
                phys_translate_count++;
                return IA64_NO_FAULT;
        }
-       else if (!(address >> 61) && warn_region0_address) {
+       else if (!region && warn_region0_address) {
                REGS *regs = vcpu_regs(vcpu);
                unsigned long viip = PSCB(vcpu,iip);
                unsigned long vipsr = PSCB(vcpu,ipsr);
@@ -1318,7 +1318,7 @@ IA64FAULT vcpu_translate(VCPU *vcpu, UINT64 address, BOOLEAN is_data, UINT64 *pt
                printk("vcpu_translate: bad address %p, viip=%p, vipsr=%p, iip=%p, ipsr=%p continuing\n", address, viip, vipsr, iip, ipsr);
        }
 
-       rr = PSCB(vcpu,rrs)[address>>61];
+       rr = PSCB(vcpu,rrs)[region];
        rid = rr & RR_RID_MASK;
        if (is_data) {
                if (vcpu_quick_region_check(vcpu->arch.dtr_regions,address)) {